/*
 * @Author: wz
 * @Date: 2020-11-27 09:30:04
 * @LastEditors: wz
 * @LastEditTime: 2021-01-28 19:17:40
 * @Description: 封装 ajax 请求
 */
import axios from 'axios'
import { clientId, baseURL } from './env'
import { refreshToken } from '@/service/uac'
import { storage } from '../utils/storage'
import router from '@/router'
import qbui from 'qb-ui'
import store from '@/store'
const { Message } = qbui
let isRefreshing = false // 标记是否正在刷新 token
let requests = [] // 存储待重发请求的数组
const errorMsg = msg =>
    Message({
        message: msg,
        type: 'error',
        duration: 2000
    })
// 创建 axios 实例
const instance = axios.create({
    baseURL,
    timeout: 30000
})
// 接口请求之前request拦截
instance.interceptors.request.use(
    config => {
        const configHeaders = {
            'authen-type': 'V2',
            clientId,
            accessToken: storage.get('accessToken') || '',
            userId: storage.get('userId') || '',
            orgCode: storage.get('orgCode') || ''
        }
        config.headers = { ...config.headers, ...configHeaders }
        console.info(`%c请求参数=====>>>：`, 'color:green')
        console.log(config)
        let loading = config.data?.loading !== false || config.params?.loading !== false
        if (loading) store.commit('loading/updateLoading', true)
        return config
    },
    error => {
        return Promise.reject(error)
    }
)

// 接口数据返回之后response拦截
instance.interceptors.response.use(
    response => {
        const { data, config, request } = response
        console.info(`%c返回结果=====>>>：`, 'color:green')
        console.log(response)
        store.commit('loading/updateLoading', false)
        //新街口返回数据不一致,包装下
        /*
            body
            code: 0
            hintMsg: null
            msg: null
            successful: true
            */
        if (Object.keys(data).includes('body')) {
            data.result = data.body
            data.responseInfo = {
                code: data.code,
                tips: data.msg,
                body: data.body
            }
        }
        //图片上传接口包装下
        if (Object.keys(data).includes('ok')) {
            data.successful = data.ok
            data.result = data.data
        }
        if (request.responseType !== 'blob' && !data.successful) {
            const errCode = data.responseInfo.code
            // token过期了
            if (['UAC0003', 'UAC0002'].includes(errCode) && !request.responseURL.includes('/uac/authen/refreshAccessToken')) {
                // 刷新token
                if (!isRefreshing) {
                    isRefreshing = true
                    return refreshToken({ refreshToken: storage.get('refreshToken'), endUserId: storage.get('userId') })
                        .then(result => {
                            let [res] = result
                            const { accessToken, refreshToken } = res
                            storage.set('accessToken', accessToken)
                            storage.set('refreshToken', refreshToken)
                            config.headers.accessToken = accessToken
                            // token 刷新后将数组的方法重新执行
                            requests.forEach(cb => cb(accessToken))
                            isRefreshing = false
                            requests = []
                            return instance(config)
                        })
                        .catch(err => {
                            isRefreshing = false
                            requests = []
                            errorMsg(`您的登录状态已失效，请重新登录！`)
                            return Promise.reject(err)
                        })
                } else {
                    // 返回未执行 resolve 的 Promise
                    return new Promise(resolve => {
                        // 用函数形式将 resolve 存入，等待刷新后再执行
                        requests.push(token => {
                            config.headers.accessToken = token
                            resolve(instance(config))
                        })
                    })
                }
            }
            // 退出登录
            if (['UAC0007', 'UAC0008'].includes(errCode)) {
                storage.clear()
                return router.replace({ path: '/login' })
            }

            // 错误提示 errCode !== 'SYS0002'
            if (errCode !== 'SYS0002') {
                errorMsg(data.responseInfo.tips)
                return Promise.reject(data.responseInfo)
            }
        }
        return data
    },
    error => {
        console.log(`%c请求出错：${error}`, 'color:red')
        if (error.message.includes('timeout')) errorMsg('网络太差了')
        if (error.response) errorMsg(error.response.data.message)
        return Promise.reject(error)
    }
)

export const to = promise => {
    return promise
        .then(res => {
            if (res.successful) return [res.result || res, null]
        })
        .catch(error => [null, error])
}

export const get = (url, params = {}) => {
    return to(
        instance({
            method: 'GET',
            url,
            params
        })
    )
}

export const post = (url, params = {}) => {
    return to(
        instance({
            method: 'POST',
            url,
            data: params
        })
    )
}
export const del = (url, params = {}) => {
    return to(
        instance({
            method: 'DELETE',
            url,
            data: params
        })
    )
}

export const put = (url, params = {}) => {
    return to(
        instance({
            method: 'PUT',
            url,
            data: params
        })
    )
}
export default instance
